// winview.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "winview.h"


#define MAX_LOADSTRING 100

//////////////////////////////////////////////////////////////////////////
// Global Variables:
Viewer *		g_pViewer;
HINSTANCE		g_hInst = NULL;
TCHAR			g_szTitle[MAX_LOADSTRING];
TCHAR			g_szWindowClass[MAX_LOADSTRING];

//////////////////////////////////////////////////////////////////////////
// Forward declarations of functions included in this code module:
HRESULT Init( HINSTANCE, int );
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
INT_PTR CALLBACK About( HWND, UINT, WPARAM, LPARAM );

//////////////////////////////////////////////////////////////////////////

int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )
{
	UNREFERENCED_PARAMETER( hPrevInstance );
	UNREFERENCED_PARAMETER( lpCmdLine );

	// Perform application initialization:
	if( FAILED(Init(hInstance, nCmdShow)) )
	{
		return FALSE;
	}

	HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINVIEW));

	// Main message loop:
	MSG msg;
	bool bQuit = false;
	while( !bQuit )
	{
		bool bRender = false;
		if( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) )
		{
			if ( msg.message == WM_QUIT )
			{
				bQuit = true;
				break;
			}
			else  if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}
		else
		{
			bRender = true;
		}

		if( bRender )
		{
			g_pViewer->Process();
			g_pViewer->Render();
		}
	}

	g_pViewer->Clean();

	return (int) msg.wParam;
}

HRESULT Init( HINSTANCE hInstance, int nCmdShow )
{
	LoadString( hInstance, IDS_APP_TITLE, g_szTitle, MAX_LOADSTRING );
	LoadString( hInstance, IDC_WINVIEW, g_szWindowClass, MAX_LOADSTRING );
	
	WNDCLASSEX wcex;
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon( hInstance, MAKEINTRESOURCE(IDI_WINVIEW) );
	wcex.hCursor		= LoadCursor( NULL, IDC_ARROW );
	wcex.hbrBackground	= (HBRUSH)( COLOR_WINDOW+1 );
	wcex.lpszMenuName	= NULL;//MAKEINTRESOURCE(IDC_WINVIEW);
	wcex.lpszClassName	= g_szWindowClass;
	wcex.hIconSm		= LoadIcon( wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL) );

	if( !RegisterClassEx( &wcex ) )
	{
		return E_FAIL;
	}

	// Store the Instance.
	g_hInst = hInstance;

	RECT rc = { 0, 0, 640, 480 };
	AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );

	HWND hWnd = CreateWindow( g_szWindowClass, g_szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL );
	if ( !hWnd )
	{
		return FALSE;
	}

	ShowWindow( hWnd, nCmdShow );
	UpdateWindow( hWnd );

	g_pViewer = new Viewer();

	if( !g_pViewer->Init( hWnd ) )
		return E_FAIL;

	return S_OK;
}

//  PURPOSE:  Processes messages for the main window.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// Parse the menu selections:
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO: Add any drawing code here...
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_SYSKEYUP:
	case WM_KEYUP:
		g_pViewer->GetInputHandler().KeyMessage( wParam, InputHandler::STATE_UP );
		break;
	case WM_SYSKEYDOWN:
	case WM_KEYDOWN:
		if( wParam>16 && wParam<18 )
		{
			g_pViewer->GetInputHandler().KeyMessage( wParam, InputHandler::STATE_DOWN );
			break;
		}
		//switch( wParam )
		//{
		//default:
		//	break;
		//}
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}
